package OpenID::Tester::Test;
use strict;

# don't override.
sub new {
    my ($class, $tester, @rest) = @_;
    my $self = bless {
        tester => $tester,
    }, $class;
    $self->init(@rest);
    return $self;
}

sub init {
    my ($self, @ctor_params) = @_;
    # override, if needed.
}

# optionally override.  class method which returns an array
# of test instances.  the default just calls the new constructor
# with no parameters (outside of the OpenID::Tester object).
# but if your test has many variants (versions, options), you'll
# want to override this to return an instance of your test for
# each variant
sub tests {
    my ($class, $tester) = @_;
    return $class->new($tester);
}

# override.  return true on success.  return 0 (or preferrably,
# die on failure, with error message or object)
sub run {
    die "Not implemented";
}

# class method.  classes should override.
sub des {
    "NO DESCRIPTION";
}

# instance method.  optionally override, if your test has
# variants.  (see class method 'tests', above).  this should
# be a short description of your options in use.  will be
# appended to the class name in output tables.  default
# string of "" is fine for tests with no variants.
sub summary {
    my $self = shift;
    return "";
}

# instance methods.  set to 1 if your test requires an OP and/or RP to run
sub needs_op { 0 }
sub needs_rp { 0 }

# instance methods.  return capabilities you need for your test
# to run.
sub needed_op_caps { $_[0]->_caps_for_version }
sub needed_rp_caps { $_[0]->_caps_for_version }

# convenience method for subclasses to get the caps required to support
# a particular version string.
sub _caps_for_version {
    my ($self, $version) = @_;

    $version ||= $self->{version};
    die "Version is not set for $self" unless $version;

    my @caps;
    push @caps, ($version =~ /\b2\.0\b/ ? 'openid2.0' : 'disableopenid2.0');
    push @caps, ($version =~ /\b1\.1\b/ ? 'openid1.1' : 'disableopenid1.1');

    return @caps;
}

############################################################################
# don't override:

sub tester { $_[0]{tester} }

# don't override, helpers:

sub gen_url {
    my ($self, $base, %opts) = @_;
    my $ret = $base;
    foreach my $k (sort keys %opts) {
        $ret .= ($ret =~ /\?/) ? "&" : "?";
        $ret .= _eurl($k) . "=" . _eurl($opts{$k});
    }
    return $ret;
}

sub status {
    my (undef, $status) = @_;
    $status =~ s/[\n\r]+$//;
    print STDERR "# $status\n";
}

sub _eurl {
    my $a = $_[0];
    $a =~ s/([^a-zA-Z0-9_\,\-.\/\\\: ])/uc sprintf("%%%02x",ord($1))/eg;
    $a =~ tr/ /+/;
    return $a;
}

1;
